/*
Assume in each of the following cases that the initial set of process user IDs is
real=1000 effective=0 saved=0 file-system=0. What would be the state of the user IDs
after the following calls?
a) setuid(2000);
b) setreuid(–1, 2000);
c) seteuid(2000);
d) setfsuid(2000);
e) setresuid(–1, 2000, 3000);
*/

// TODO: boring topic exercises undone

#include <stdio.h>
#include <stdlib.h>
// -D_GNU_SOURCE add feature_test_macro
#include <unistd.h>
#include <sys/fsuid.h>


void
print_process_credentials(void)
{
  uid_t ruid, euid, suid, fsuid;
  fsuid = setfsuid(0);
  if (getresuid(&ruid, &euid, &suid) == -1)
    return;
  printf("ruid: %ld, euid: %ld, suid %ld, fsuid %ld\n",
         ruid, euid, suid, fsuid);

  gid_t rgid, egid, sgid, fsgid;
  fsgid = setfsgid(0);
  if (getresuid(&rgid, &egid, &sgid) == -1)
    return;
  printf("rgid: %ld, egid: %ld, sgid %ld, fsgid %ld\n",
         rgid, egid, sgid, fsgid);

  long ngroups = sysconf(_SC_NGROUPS_MAX) + 1;
  gid_t supp_groups[ngroups];
  ssize_t curr_ngroups = getgroups(ngroups, supp_groups);
  printf("supplementary groups:\n");
  for (int i = 0; i < curr_ngroups; ++i)
    printf("%ld ", supp_groups[i]);
  printf("\n");
}

int
main(void)
{
  print_process_credentials();
  // -- setuid(2000);
  /*
ruid: 2000, euid: 2000, suid 2000, fsuid 2000
rgid: 2000, egid: 2000, sgid 2000, fsgid 0
   */

  // -- printf("%d\n", setreuid(-1, 2000));
  // ruid: 1000, euid: 2000, suid 2000, fsuid 2000

  // seteuid(2000);
  // -- ruid: 1000, euid: 2000, suid 0, fsuid 2000

  // setfsuid(2000);
  // -- ruid: 1000, euid: 0, suid 0, fsuid 2000

  // setresuid(-1, 2000, 3000);
  // -- ruid: 1000, euid: 2000, suid 3000, fsuid 2000
  print_process_credentials();

  return EXIT_SUCCESS;
}
